<template>
  <div class="app-container">
    <el-card class="scan-card">
      <template #header>
        <div class="card-header">
          <el-row class="mb-1" style="text-align: center">
            <el-col :span="12">
              <el-button v-if="!isScanning" type="primary" @click="scanInviteCode">
                {{ $t("visitor.sanqrcode") }}
              </el-button>
            </el-col>
            <el-col :span="12">
              <el-button type="warning" @click="inputVisitorInfo">
                {{ $t("visitor.noinviteVisitor") }}
              </el-button>
            </el-col>
          </el-row>
          <el-row
            v-if="hasInviateCode && (formData.id == 0 || formData.tagNo == '')"
            class="mb-1"
            style="text-align: center"
          >
            <el-col :span="12" style="display: flex; justify-content: center; align-items: center">
              <div
                class="scanBox"
                :style="{
                  backgroundImage: `url(${scan})`,
                  width: scanBoxWidth,
                  height: scanBoxWidth,
                }"
              >
                <div v-if="formData.id">
                  <el-icon size="50" color="green"><Select /></el-icon>
                </div>
                <div v-else>{{ $t("visitor.scanInviteCode") }}</div>
              </div>
            </el-col>
            <el-col :span="12" style="display: flex; justify-content: center; align-items: center">
              <div
                class="scanBox"
                :style="{
                  backgroundImage: `url(${scan})`,
                  width: scanBoxWidth,
                  height: scanBoxWidth,
                }"
              >
                <div v-if="formData.tagNo" class="text-center">
                  <el-icon size="50" color="green"><Select /></el-icon>
                </div>
                <div v-else>{{ $t("visitor.scanTag") }}</div>
              </div>
            </el-col>
          </el-row>
        </div>
      </template>
      <div>
        <div id="reader" style="display: none; width: 100%" />
        <button v-if="isScanning" @click="stopScanning">{{ $t("common.stopScanning") }}</button>
      </div>
      <div v-if="hasNoInviateCode" class="mb-2">
        <el-card>
          <el-form ref="iFormRefx" :model="xformData" :rules="rulesx">
            <el-form-item :label="$t('visitor.tagNo')" prop="tagNo">
              <el-input
                v-model="xformData.tagNo"
                :placeholder="$t('common.plsInput') + $t('visitor.tagNo')"
              >
                <template #append>
                  <el-button v-if="!isScanning" :icon="CameraFilled" @click="scanTagCode2" />
                </template>
              </el-input>
            </el-form-item>
            <el-form-item :label="$t('visitor.name')" prop="name">
              <el-input
                v-model="xformData.name"
                :placeholder="$t('common.plsInput') + $t('visitor.name')"
              />
            </el-form-item>
            <el-form-item :label="$t('visitor.companyName')" prop="companyName">
              <el-input
                v-model="xformData.companyName"
                :placeholder="$t('common.plsInput') + $t('visitor.companyName')"
              />
            </el-form-item>
            <el-form-item :label="$t('visitor.phone')" prop="phone">
              <el-input
                v-model="xformData.phone"
                :placeholder="$t('common.plsInput') + $t('visitor.phone')"
              />
            </el-form-item>
          </el-form>
          <template #footer>
            <el-row class="mt-2" style="text-align: center">
              <el-col :span="12">
                <el-button size="large" @click="cancelBind">{{ $t("visitor.backTo") }}</el-button>
              </el-col>
              <el-col :span="12">
                <el-button size="large" type="primary" @click="xhandleSubmit">
                  {{ $t("common.confirm") }}
                </el-button>
              </el-col>
            </el-row>
          </template>
        </el-card>
      </div>
      <div v-if="hasInviateCode" class="mb-2">
        <el-card>
          <el-descriptions :title="$t('visitor.info')" :column="1" border>
            <el-descriptions-item
              v-if="formData.id > 0"
              :label="$t('visitor.tagNo')"
              label-align="right"
              align="center"
            >
              <el-input v-model="formData.tagNo" style="width: 240px" />
            </el-descriptions-item>
            <div v-if="formData.id > 0">
              <el-descriptions-item
                :label="$t('visitor.name')"
                label-align="right"
                align="center"
                label-class-name="my-label"
                class-name="my-content"
                width="60px"
              >
                {{ detailData.visitorName }}
              </el-descriptions-item>
              <el-descriptions-item :label="$t('visitor.dept')" label-align="right" align="center">
                {{ detailData.deptName }}
              </el-descriptions-item>
              <el-descriptions-item
                :label="$t('visitor.purpose')"
                label-align="right"
                align="center"
              >
                {{ detailData.purposeName }}
              </el-descriptions-item>
              <el-descriptions-item
                :label="$t('visitor.planInAt')"
                label-align="right"
                align="center"
              >
                {{ dayjs(detailData.planInAt).format("YYYY-MM-DD HH:mm:ss") }}
              </el-descriptions-item>
              <el-descriptions-item
                :label="$t('visitor.planOutAt')"
                label-align="right"
                align="center"
              >
                {{ dayjs(detailData.planOutAt).format("YYYY-MM-DD HH:mm:ss") }}
              </el-descriptions-item>
              <el-descriptions-item
                :label="$t('visitor.status')"
                label-align="right"
                align="center"
              >
                <el-tag v-if="detailData.status == 0" type="info">
                  {{ t("visitor.bindStatus.0") }}
                </el-tag>
                <el-tag v-if="detailData.status == 1" type="primary">
                  {{ t("visitor.bindStatus.1") }}
                </el-tag>
                <el-tag v-if="detailData.status == 2" type="danger">
                  {{ t("visitor.bindStatus.2") }}
                </el-tag>
              </el-descriptions-item>
              <el-descriptions-item
                v-if="detailData.status > 0"
                :label="$t('visitor.actInAt')"
                label-align="right"
                align="center"
              >
                <el-tag type="info">
                  {{ dayjs(detailData.actInAt).format("YYYY-MM-DD HH:mm:ss") }}
                </el-tag>
              </el-descriptions-item>
              <el-descriptions-item
                v-if="detailData.status == 2"
                :label="$t('visitor.actOutAt')"
                label-align="right"
                align="center"
              >
                <el-tag type="info">
                  {{ dayjs(detailData.actOutAt).format("YYYY-MM-DD HH:mm:ss") }}
                </el-tag>
              </el-descriptions-item>
            </div>
          </el-descriptions>
          <template #footer>
            <el-row class="mt-2" style="text-align: center">
              <el-col :span="12">
                <el-button size="large" @click="cancelBind">{{ $t("visitor.backTo") }}</el-button>
              </el-col>
              <el-col v-if="detailData.status == 0" :span="12">
                <el-button size="large" type="primary" @click="handleSubmit">
                  {{ $t("common.confirm") }}
                </el-button>
              </el-col>
            </el-row>
          </template>
        </el-card>
      </div>
    </el-card>
  </div>
</template>

<script setup lang="ts">
import qrcodeScanSound from "@/assets/qrcodescan.mp3";
import { CameraFilled } from "@element-plus/icons-vue";
import scan from "@/assets/scan.png";
import { Html5Qrcode } from "html5-qrcode";
import { ref } from "vue";
import dayjs from "dayjs";
import { useI18n } from "vue-i18n";
const { t } = useI18n();
defineOptions({
  name: "BindTag",
  inheritAttrs: false,
});

const hasNoInviateCode = ref<boolean>(false);
const hasInviateCode = ref<boolean>(false);

const isScanning = ref<boolean>(false);
const html5QrCode = ref<Html5Qrcode | null>(null);
const isScanedInviteCode = ref<boolean>(false);
const isScanedTagCode = ref<boolean>(false);
const screenWidth = window.innerWidth;
const scanBoxWidth = ref(screenWidth * 0.3 + "px");
import VisitorAPI, { BindTagForm, InvitePageVO, NoInviteForm } from "@/api/visitor/index";
const iFormRef = ref(ElForm);

const iFormRefx = ref(ElForm);

const formData = reactive<BindTagForm>({
  id: 0,
  tagNo: "",
});

const xformData = reactive<NoInviteForm>({
  name: "",
  companyName: "",
  phone: "",
  tagNo: "",
  status: 1,
});
const rulesx = reactive({
  tagNo: [{ required: true, message: t("common.plsInput") + t("visitor.tagNo"), trigger: "blur" }],
  name: [{ required: true, message: t("common.plsInput") + t("visitor.name"), trigger: "blur" }],
  companyName: [
    { required: true, message: t("common.plsInput") + t("visitor.companyName"), trigger: "blur" },
  ],
  phone: [{ required: true, message: t("common.plsChoose") + t("visitor.phone"), trigger: "blur" }],
});

const detailData = reactive<InvitePageVO>({
  id: 0,
  visitorName: "",
  deptName: "",
  purposeName: "",
  planInAt: "",
  planOutAt: "",
  tagNo: "",
  actInAt: "",
  actOutAt: "",
  status: 0,
  opName: "",
});

const rules = reactive({
  tagNo: [{ required: true, message: t("common.plsInput") + t("visitor.tagNo"), trigger: "blur" }],
});

function cancelBind() {
  formData.id = 0;
  formData.tagNo = "";

  detailData.id = 0;
  detailData.visitorName = "";
  detailData.deptName = "";
  detailData.purposeName = "";
  detailData.planInAt = "";
  detailData.planOutAt = "";
  detailData.tagNo = "";
  detailData.status = 0;
  hasInviateCode.value = false;
  hasNoInviateCode.value = false;
  stopScanning();
}

function xhandleSubmit() {
  iFormRefx.value.validate((valid: boolean) => {
    if (valid) {
      xformData.tagNo = xformData.tagNo.slice(-6).toLocaleUpperCase();
      VisitorAPI.createNoInviteVisitor(xformData)
        .then((res) => {
          if (res.data.code === 200) {
            ElMessage.success(res.data.message);
            xformData.tagNo = "";
            xformData.name = "";
            xformData.companyName = "";
            xformData.phone = "";
          } else {
            ElMessage.error(res.data.message);
          }
        })
        .catch((err) => {});
    }
  });
}

function handleSubmit() {
  if (formData.id == 0) {
    ElMessage.error(t("visitor.pleaseScanInviteCode"));
    return;
  }
  if (formData.tagNo == "") {
    ElMessage.error(t("visitor.pleaseScanTagCode"));
    return;
  }
  if (detailData.status != 0) {
    ElMessage.error(t("visitor.tagHasBound"));
    return;
  }
  formData.tagNo = formData.tagNo.slice(-6).toLocaleUpperCase();
  VisitorAPI.bindTag(formData)
    .then((res) => {
      if (res.data.code === 200) {
        ElMessage.success(res.data.message);
        formData.id = 0;
        formData.tagNo = "";

        detailData.id = 0;
        detailData.visitorName = "";
        detailData.deptName = "";
        detailData.purposeName = "";
        detailData.planInAt = "";
        detailData.planOutAt = "";
        detailData.tagNo = "";
        detailData.status = 0;
      } else {
        ElMessage.error(res.data.message);
      }
    })
    .catch((err) => {});
}

function inputVisitorInfo() {
  hasInviateCode.value = false;
  hasNoInviateCode.value = true;
  setTimeout(function () {
    stopScanning();
  }, 500);
}

function scanInviteCode() {
  console.log("scanInviteCode");
  isScanedInviteCode.value = false;
  isScanedTagCode.value = false;
  hasInviateCode.value = true;
  hasNoInviateCode.value = false;
  startScanning("invite");
}

function scanTagCode() {
  startScanning("tag");
}

const startScanning = (type: string) => {
  html5QrCode.value = new Html5Qrcode("reader");
  isScanning.value = true;

  const readerElement = document.getElementById("reader");
  if (readerElement) {
    readerElement.style.display = "block";
  }

  html5QrCode.value
    .start(
      { facingMode: "environment" },
      {
        fps: 2, // Scan speed，2 times a second
        qrbox: 250,
      },
      (decoded: string) => {
        playSound();
        console.log(decoded);
        if (decoded.includes("{")) {
          type = "invite";
        } else {
          type = "tag";
        }
        if (type === "invite") {
          if (!isJSON(decoded)) {
            ElMessage.error(t("visitor.inviteCodeError"));
            return;
          }

          let codeRes = JSON.parse(decoded);
          const formatJson = "inviteCode" in codeRes;
          if (!formatJson) {
            ElMessage.error(t("visitor.inviteCodeError"));
            return;
          }
          if (codeRes.inviteCode === "" || codeRes.inviteCode.length < 32) {
            ElMessage.error(t("visitor.inviteCodeError"));
            return;
          }
          VisitorAPI.getInviteInfoByInviteCode(codeRes.inviteCode)
            .then((res) => {
              if (res) {
                detailData.visitorName = res.visitorName;
                detailData.deptName = res.deptName;
                detailData.purposeName = res.purposeName;
                detailData.tagNo = formData.tagNo ? formData.tagNo : res.tagNo;
                detailData.actInAt = dayjs(res.actInAt).format("YYYY-MM-DD HH:mm:ss");
                detailData.actOutAt = dayjs(res.actOutAt).format("YYYY-MM-DD HH:mm:ss");
                detailData.status = res.status;
                detailData.planInAt = dayjs(res.planInAt).format("YYYY-MM-DD HH:mm:ss");
                detailData.planOutAt = dayjs(res.planOutAt).format("YYYY-MM-DD HH:mm:ss");
                formData.id = res.id;
                isScanedInviteCode.value = true;

                if (isScanedInviteCode.value && isScanedTagCode.value) {
                  stopScanning();
                }
              }
            })
            .catch((err) => {});
        } else if (type === "tag") {
          formData.tagNo = decoded.slice(-6).toUpperCase();
          detailData.tagNo = decoded.slice(-6).toUpperCase();
          isScanedTagCode.value = true;

          if (isScanedInviteCode.value && isScanedTagCode.value) {
            stopScanning();
          }
        }
      },
      (err: any) => {
        isScanning.value = false;
      }
    )
    .catch((err: Error) => {
      isScanning.value = false;
    });
};

function isJSON(str: string): boolean {
  try {
    JSON.parse(str);
    return true;
  } catch (e) {
    return false;
  }
}

const stopScanning = () => {
  if (html5QrCode.value) {
    html5QrCode.value
      .stop()
      .then(() => {
        isScanning.value = false;
        isScanedInviteCode.value = false;
        isScanedTagCode.value = false;
        html5QrCode.value = null;
        const readerElement = document.getElementById("reader");
        if (readerElement) {
          readerElement.style.display = "none";
        }
      })
      .catch((err: Error) => {});
  }
};

const playSound = () => {
  const audio = new Audio(qrcodeScanSound);
  audio.play().catch((error: Error) => {});
};

function scanTagCode2() {
  startScanning2("tag");
}

const startScanning2 = (type: string) => {
  html5QrCode.value = new Html5Qrcode("reader");
  isScanning.value = true;

  const readerElement = document.getElementById("reader");
  if (readerElement) {
    readerElement.style.display = "block";
  }

  html5QrCode.value
    .start(
      { facingMode: "environment" },
      {
        fps: 2, // Scan speed，2 times a second
        qrbox: 250,
      },
      (decoded: string) => {
        playSound();
        xformData.tagNo = decoded.slice(-6);
        stopScanning();
      },
      (err: any) => {
        isScanning.value = false;
      }
    )
    .catch((err: Error) => {
      isScanning.value = false;
    });
};

watch(
  () => formData.tagNo,
  (newVal, oldVal) => {
    if (newVal && newVal.trim() !== "") {
      stopScanning();
    }
  }
);
</script>

<style scoped>
.scan-card .el-card__header {
  background: #cdd0d6;
}
.scanBox {
  max-width: 100px;
  max-height: 100px;
  text-align: center;
  background-size: contain;
  background-color: #e1e1e1;
  display: flex;
  justify-content: center; /* 水平居中 */
  align-items: center;
  padding: 20px;
}
#reader video {
  width: 100%;
  height: 100%;
}
</style>
